---
title: 桥接模式（简单了解）
description: 将抽象和实现解耦，让它们可以独立变化。抽象并非是抽象类或接口，而是被抽象出来的一套类库，它只包含骨架代码。
---
## 原理
桥接模式的英文是 Bridge Design Pattern, 它会将抽象和实现解耦，让它们可以独立变化。



JDBC 驱动是桥接模式的经典应用，具体的代码如下所示：

```java
Class.forName("com.mysql.jdbc.Driver");// 加载及注册 JDBC 驱动程序
String url = "jdbc:mysql://localhost:3306/sample_db?user=root&password=123456";
Connection con = DriverManager.getConnection(url);
Statement stmt = con.createStatement();
String query = "select * from test";
ResultSet rs = stmt.executeQuery(query);
while(rs.next()) { rs.getString(1); rs.getInt(2);}
```
如果我们想要把 MySQL 数据库换成 Oracle 数据库，只需要把第一行代码中的 com.mysql.jdbc.Driver 换成 oracle.jdbc.driver.OracleDriver 就可以了。


那么如此优雅的切换数据库是如何实现的呢，com.mysql.jdbc.Driver 这个类的部分代码如下：

```java
package com.mysql.jdbc;
import java.sql.SQLException;

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
  static {
    try {
      java.sql.DriverManager.registerDriver(new Driver());
    } catch (SQLException E) {
      throw new RuntimeException("Can't register driver!");
    }
  }

  /**
   * Construct a new driver and register it with DriverManager
   * @throws SQLException if a database error occurs.
   */
  public Driver() throws SQLException {
    // Required for Class.forName().newInstance()
  }
}
```
当执行 Class.forName("com.mysql.jdbc.Driver"); 的时候，实际上是做了两件事情，第一件事情是要求 JVM 查找并加载指定的 Driver 类，第二件事情是执行改类的静态代码，也就是将 MySQL
 Driver 注册到 DriverManager 类中。

接下来看下 DriverManger 类的作用，当把具体的 Driver 实现类（比如 com.mysql.jdbc.Driver）注册到 DriverManager 之后，后续所有对 JDBC 接口的调用，都会委派到具体的 Driver 实现类来执行。而Driver 实现类都实现了相同的接口 （java.sql.Driver）,这也是可以灵活切换 Driver 的原因。


```java
public class DriverManager {
  private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<DriverInfo>();

  //...
  static {
    loadInitialDrivers();
    println("JDBC DriverManager initialized");
  }
  //...

  public static synchronized void registerDriver(java.sql.Driver driver) throws SQLException {
    if (driver != null) {
      registeredDrivers.addIfAbsent(new DriverInfo(driver));
    } else {
      throw new NullPointerException();
    }
  }

  public static Connection getConnection(String url, String user, String password) throws SQLException {
    java.util.Properties info = new java.util.Properties();
    if (user != null) {
      info.put("user", user);
    }
    if (password != null) {
      info.put("password", password);
    }
    return (getConnection(url, info, Reflection.getCallerClass()));
  }
  //...
}
```
桥接模式的定义是“将抽象和实现解耦”，让它们可以独立变化，JDBC 就相当于抽象，具体的 Driver 就是实现。JDBC 和 Driver 独立开发，通过对象之间的组合关系，组装在一起，JDBC 的所有逻辑操作，最终都委托给 Driver 来执行。

